package com.tn.rtdata;

import java.io.Serializable;
import java.util.UUID;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

/**
 * The event object used to pass data to <code>DataListener</code>s.
 *
 * @see DataListener
 */
public class DataEvent<T> implements Serializable
{
  public static enum Type
  {
    INITIAL,
    RESET,
    ADD,
    UPDATE,
    DELETE
  }

  private String id;
  private Type type;
  private T newValue;
  private T oldValue;

  /**
   * Creates a new <code>DataEvent</code> initialized with the <code>newValue</code> and <code>oldValue</code>.
   */
  public DataEvent(Type type, T newValue, T oldValue)
  {
    this(UUID.randomUUID().toString(), type, newValue, oldValue);
  }

  /**
   * Creates a new <code>DataEvent</code> initialized with the <code>newValue</code> and <code>oldValue</code>.
   */
  public DataEvent(String id, Type type, T newValue, T oldValue)
  {
    this.id = id;
    this.type = type;
    this.newValue = newValue;
    this.oldValue = oldValue;
  }

  /**
   * Returns the id.
   */
  public String getId()
  {
    return id;
  }

  /**
   * Returns the new value.
   */
  public T getNewValue()
  {
    return newValue;
  }

  /**
   * Returns the old value.
   */
  public T getOldValue()
  {
    return oldValue;
  }

  /**
   * Returns the type.
   */
  public Type getType()
  {
    return type;
  }

  /**
   * Compares this object to another for equality.  For another object to be considered equal to a <code>DataEvent</code> the other object
   * must be a <code>DataEvent</code> and must have been initialized with the same values.
   *
   * @param other the other object.
   *
   * @return <code>true</code> if the objects are considered equal, otherwise <code>false</code>.
   */
  @Override
  public boolean equals(Object other)
  {
    return this == other || other != null && getClass() == other.getClass() &&
      new EqualsBuilder()
        .append(getId(), ((DataEvent)other).getId())
        .append(getType(), ((DataEvent) other).getType())
        .append(getNewValue(), ((DataEvent)other).getNewValue())
        .append(getOldValue(), ((DataEvent)other).getOldValue())
        .isEquals();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public int hashCode()
  {
    return new HashCodeBuilder()
      .append(getId())
      .append(getType())
      .append(getNewValue())
      .append(getOldValue())
      .toHashCode();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public String toString()
  {
    return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
      .append("id", getId())
      .append("type", getType())
      .append("newValue", getNewValue())
      .append("oldValue", getOldValue())
      .toString();
  }
}
